# SPIM S20 MIPS simulator.
# Test of memory mapped IO.
#
# Copyright (C) 1992-2004 James Larus, larus@cs.wisc.edu.
# ALL RIGHTS RESERVED.
#
# SPIM is distributed under the following conditions:
#
# You may make copies of SPIM for your own use and modify those copies.
#
# All copies of SPIM must retain my name and copyright notice.
#
# You may not sell SPIM or distributed SPIM in conjunction with a commerical
# product or service without the expressed written consent of James Larus.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE.
#

# $Header: /u/faculty/larus/Software/larus/SPIM/Tests/RCS/tt.io.s,v 1.3 1994/01/18 03:23:44 larus Exp $


	.data
prompt: .asciiz "SPIM IO Test.\nOnly runs with -mapped_io flag.\nPlease type 6 input lines:\n"
nl:	.asciiz "\n"
rup:	.asciiz "up\n"
rdown:	.asciiz "down\n"
rleft:	.asciiz "left\n"
rright:	.asciiz "right\n"

	.text
	.globl main
main:
	li $v0 4
	la $a0 prompt
	syscall


# Register usage:
#		s0		loop counter
#		t0		address of recv_ctrl
#		t1		address of recv_buffer
#		t2		address of trans_ctrl
#		t3		address of trans_buffer
#		t4, t5		temporaries
#		t6		char read from input
#		t7		1 => char in t6

	li $s0 3		# loop counter


	li $t0 0xffff0000	# recv ctrl
	li $t1 0xffff0004	# recv buf
	li $t2 0xffff0008	# trans ctrl
	li $t3 0xffff000c	# trans buf

# First, read and echo 3 lines of input by polling the IO registers, not through
# interrupts:

	mtc0 $0 $12		# Clear IE bit in Status reg to disable interrupts

l1:
	lw $t4 0($t0)		# Wait for receiver ready
	and $t4 $t4 1
	beq $t4 0 l1

	lw $t6 0($t1)		# Read character

l2:
	lw $t4 0($t2)		# Wait for transmitter ready
	and $t4 $t4 1
	beq $t4 0 l2
	
	li $v0,9			# Get two 4-int arrays to pass to case statement
	add $a0,$0,16		# one stored in v0, one in v1
	syscall
	add $v1,$0,$v0
	li $v0,9
	add $a0,$0,16
	syscall
	add $a0 $0 0x77     # store the values to compare with in v0
	sw $a0,0($v0)		
	add $a0 $0 0x73
	sw $a0,4($v0)
	add $a0 $0 0x61
	sw $a0,8($v0)
	add $a0 $0 0x64
	sw $a0,12($v0)
	la $a0,up			# store the corresponding subroutines to call
	sw $a0,0($v1)		
	la $a0,down
	sw $a0,4($v1)
	la $a0,left
	sw $a0,8($v1)
	la $a0,right
	sw $a0,12($v1)
	add $a0,$0,$t6		# store the value to compare in a0
	add $a1,$0,4		# store the number of values to compare to in a1
	jal casestatement

	beq $t6 0xa decr	# New line (nl)
	bne $t6 0xd l1		# Carriage return (cr)

decr:
	add $s0 $s0 -1		# Decrement line counter
	bne $s0 0 l1		# If not zero, get another line
	
# Done echoing, so terminate program.
	li $v0 10
	syscall			# syscall 10 (exit)

# a0: value to compate, a1: number of elements, v0: comparators, v1: subroutines
casestatement:		
	sub $sp,$sp,12
	sw $t1,8($sp)
	sw $ra,4($sp)
	sw $t0,0($sp)
casestatement_loop:
	lw $t0,0($v0)
	lw $t1,0($v1)
	beq $a0,$t0,casestement_call
	add $a1,$a1,-1
	add $v0,$v0,4
	add $v1,$v1,4
	bne $a1,$0 casestatement_loop
	beq $a1,$0 casestatement_done
casestement_call:
	jal $t1
casestatement_done:
	lw $t1,8($sp)
	lw $ra,4($sp)
	lw $t0,0($sp)
	add $sp,$sp,12
	jr $ra

up:
	li $v0 4
	la $a0 rup
	syscall
	jr $ra
down:
	li $v0 4
	la $a0 rdown
	syscall
	jr $ra
left:
	li $v0 4
	la $a0 rleft
	syscall
	jr $ra
right:
	li $v0 4
	la $a0 rright
	syscall
	jr $ra
